package com.sinaapp.mspring.aop;

import java.lang.reflect.Method;
import java.util.Date;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;

import com.sinaapp.mspring.pojo.SysLog;
import com.sinaapp.mspring.service.SysLogServiceI;


/**
 * 系统日志AOP
 * @author binchao
 *
 */
@Aspect
public class LogAspect {
	
	@Autowired
	private SysLogServiceI sysLogService;
	
	/**
	 * 添加业务逻辑方法切入点
	 */
	@Pointcut("execution(* com.sinaapp.myresume.service.*.insert*(..))")
	public void insertServiceCall() {}
	
	/**
	 * 修改业务逻辑方法切入点
	 */
	@Pointcut("execution(* com.sinaapp.myresume.service.*.update*(..))")
	public void updateServiceCall() {}
	
	/**
	 * 删除业务逻辑方法切入点
	 */
	@Pointcut("execution(* com.sinaapp.myresume.service.*.delete*(..))")
	public void deleteServiceCall() {}
	
	/**
	 * 查询业务逻辑方法切入点
	 */
	@Pointcut("execution(* com.sinaapp.myresume.service.*.select*(..))")
	public void selectServiceCall() {}
	
	/**
	 * 管理员添加操作日志(后置通知)
	 * @param joinPoint
	 * @param rtv
	 * @throws Throwable
	 */
	@AfterReturning(value="insertServiceCall()", argNames="rtv", returning="rtv")
	public void insertServiceCallCalls(JoinPoint joinPoint, Object rtv) throws Throwable {
		
		//获取用户ip
		String userIp = sysLogService.loginUserIp();
		
		//判断参数
		if(joinPoint.getArgs() == null) {
			return;
		}
		
		//获取方法名
		String methodName = joinPoint.getSignature().getName();
		
		//获取操作内容
		String opContent = adminOptionContent(joinPoint.getArgs(), methodName);
		
		//创建日志对象
		SysLog sysLog = new SysLog();
		sysLog.setUserid(1);
		sysLog.setIp(userIp);
		sysLog.setCreatedate(new Date());
		sysLog.setContent(opContent);
		sysLog.setOperation("添加");
		
		sysLogService.log(sysLog);  //添加日志
	}
	
	/**
	 * 管理员更新操作日志(后置通知)
	 * @param joinPoint
	 * @param rtv
	 * @throws Throwable
	 */
	@AfterReturning(value="updateServiceCall()", argNames="rtv", returning="rtv")
	public void updateServiceCallCalls(JoinPoint joinPoint, Object rtv) throws Throwable {
		
		//获取用户ip
		String userIp = sysLogService.loginUserIp();

        //判断参数  
        if(joinPoint.getArgs() == null){//没有参数  
            return;  
        }  
          
        //获取方法名  
        String methodName = joinPoint.getSignature().getName();  
          
        //获取操作内容  
        String opContent = adminOptionContent(joinPoint.getArgs(), methodName);  
          
        //创建日志对象
        SysLog sysLog = new SysLog();
        sysLog.setUserid(1);
        sysLog.setIp(userIp);
        sysLog.setCreatedate(new Date());
        sysLog.setContent(opContent);
        sysLog.setOperation("修改");
      		
        sysLogService.log(sysLog);  //添加日志
		
	}
	
	/**
	 * 管理员查询操作日志(后置通知)
	 * @param joinPoint
	 * @param rtv
	 * @throws Throwable
	 */
	@AfterReturning(value="selectServiceCall()", argNames="rtv", returning="rtv")
	public void selectServiceCallCalls(JoinPoint joinPoint, Object rtv) throws Throwable {
		
		//获取登录用户ip
		String userIp = sysLogService.loginUserIp();
          
        //判断参数  
        if(joinPoint.getArgs() == null){//没有参数  
            return;  
        }  
          
        //获取方法名  
        String methodName = joinPoint.getSignature().getName();  
          
        //获取操作内容  
        String opContent = adminOptionContent(joinPoint.getArgs(), methodName);  
          
        //创建日志对象
        SysLog sysLog = new SysLog();
        sysLog.setUserid(1);
        sysLog.setIp(userIp);
        sysLog.setCreatedate(new Date());
        sysLog.setContent(opContent);
        sysLog.setOperation("查询");
      		
        sysLogService.log(sysLog);  //添加日志
		
	}
	
	
	/**
	 * 使用java反射来获取被拦截方法(insert、update)的参数值
	 * 将参数拼接为操作内容
	 * @param args
	 * @param mName
	 * @return
	 * @throws Exception
	 */
	public String adminOptionContent(Object[] args, String mName) throws Exception {
		
		if(args == null) {
			return null;
		}
		
		StringBuffer rs = new StringBuffer();
		rs.append(mName);
		String className = null;
		int index = 1;
		//遍历参数对象
		for (Object info : args) {
			//获取对象类型
			className = info.getClass().getName();
			className = className.substring(className.lastIndexOf(".") + 1);
			rs.append("[参数" + index + ",类型:" + className + ",值：");
			
			//获取对象的所有方法
			Method[] methods = info.getClass().getDeclaredMethods();
			
			//遍历方法，判断get方法
			for (Method method : methods) {
				
				String methodName = method.getName();
				//判断是不是get方法
				if(methodName.indexOf("get") == -1) { //不是get方法
					continue;
				}
				
				Object rsValue = null;
				
				try {
					//调用get方法，获取返回值
					rsValue = method.invoke(info);
					
					if(rsValue == null) { //没有返回值
						continue;
					}
				} catch (Exception e) {
					continue;
				}
				
				//将值加入内容中
				rs.append("(" + methodName + ":" + rsValue + ")");
			}
			
			rs.append("]");
			
			index++;
		}
		
		return rs.toString();
	}
}
